﻿#ifndef QTOSGWIDGET_H
#define QTOSGWIDGET_H


#pragma execution_character_set("utf-8")
#include "gameworld.h"

#include <QtCore>
#include <QOpenGLWidget>
#include <osgViewer/Viewer>
#include <osg/Drawable>
#include <osg/ShapeDrawable>
#include <osgGA/TrackballManipulator>
#include <osg/Material>
#include <QMouseEvent>
#include <iostream>


class QtOSGWidget : public QOpenGLWidget{
private:

 osg::Camera * camera;
 osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _mGraphicsWindow;
 osg::ref_ptr<osgViewer::Viewer> _mViewer;
 qreal m_scaleX,m_scaleY;
 osg::ref_ptr<osgGA::EventQueue> queue ;
public:
    QtOSGWidget(QWidget *parent=nullptr,qreal scaleX=1, qreal scaleY=1)
        : QOpenGLWidget(parent),
          _mGraphicsWindow(new osgViewer::GraphicsWindowEmbedded(this->x(), this->y(),
                                                                 this->width(), this->height())),
           m_scaleX(scaleX),
          m_scaleY(scaleY)
    {
        camera=new osg::Camera;
        camera->setViewport(0,0,this->width(),this->height());
        camera->setClearColor(osg::Vec4(0.2f,0.2f,0.3f,1.0f));
        float aspectRatio=static_cast<float>(this->width()) / static_cast<float>( this->height());
        //fovy：垂直视野角度（Field of View），以角度为单位。
        //      aspectRatio：视口的宽高比（宽度除以高度）。
        //      zNear：近裁剪面距离。
        //      zFar：远裁剪面距离。
        camera->setProjectionMatrixAsPerspective(30.f,aspectRatio,1.f,1000.f);
        camera->setGraphicsContext(_mGraphicsWindow );

        _mViewer=new osgViewer::Viewer;
//        _mViewer=new osgViewer::Viewer;

        _mViewer->setCamera(camera);

        osgGA::TrackballManipulator *manipulator=new osgGA::TrackballManipulator;
        manipulator->setAllowThrow(false);
        this->setMouseTracking(true);
        //我感觉这个一点用都没有
        this->_mViewer->setCameraManipulator(manipulator);

        _mViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
        _mViewer->realize();
        queue=_mViewer->getEventQueue();

        //没有了这个输入的按键就没啥用处
        this->setFocus();


    }

    virtual ~QtOSGWidget(){}

    void setScale(qreal X, qreal Y)
    {
        m_scaleX = X;
        m_scaleY = Y;
        this->resizeGL(this->width(), this->height());
    }

public:
    virtual void paintGL() {
      _mViewer->frame();
    }

    virtual void resizeGL(int width,int height){
        this->getEventQueue()->windowResize(this->x()*m_scaleX, this->y() * m_scaleY, width*m_scaleX, height*m_scaleY);
        _mGraphicsWindow->resized(this->x()*m_scaleX, this->y() * m_scaleY, width*m_scaleX, height*m_scaleY);
        osg::Camera* camera = _mViewer->getCamera();
        camera->setViewport(0, 0, this->width()*m_scaleX, this->height()* m_scaleY);

    }



    osgGA::EventQueue* getEventQueue() const {
      osgGA::EventQueue* eventQueue = _mGraphicsWindow->getEventQueue();
      return eventQueue;
    }

    virtual void mousePressEvent(QMouseEvent* event)
    {
        unsigned int button = 0;
        switch (event->button()){
        case Qt::LeftButton:
            button = 1;
            std::cout<< "Tessst" << std::endl;
            break;
        case Qt::MiddleButton:
            button = 2;
            break;
        case Qt::RightButton:
            button = 3;
            break;
        default:
            break;
        }
        this->getEventQueue()->mouseButtonPress(event->x()*m_scaleX, event->y()*m_scaleY, button);
    }
    virtual void mouseReleaseEvent(QMouseEvent* event)
    {
        unsigned int button = 0;
        switch (event->button()){
        case Qt::LeftButton:
            button = 1;
            std::cout<< "Testrelease" << std::endl;
            break;
        case Qt::MiddleButton:
            button = 2;
            break;
        case Qt::RightButton:
            button = 3;
            break;
        default:
            break;
        }
        this->getEventQueue()->mouseButtonRelease(event->x()*m_scaleX, event->y()*m_scaleY, button);
    }
    virtual void mouseMoveEvent(QMouseEvent* event)
      {

          this->getEventQueue()->mouseMotion(event->x()*m_scaleX, event->y()*m_scaleY);
      }


    void wheelEvent(QWheelEvent *event){
        int delta=event->delta();
        osgGA::GUIEventAdapter::ScrollingMotion motion=
                delta>0?osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN;
        this->getEventQueue()->mouseScroll(motion);
    }

    virtual bool event(QEvent* event)
    {
        bool handled = QOpenGLWidget::event(event);
        this->update();
        return handled;
    }

    osg::ref_ptr<osgViewer::Viewer> getViewer(){
          return _mViewer;
    }


    void setCamera(osg::Camera* camera)
    {
        _mViewer->setCamera(camera);
    }
    void setGeodeSc(osg::Group* geode)
    {
          _mViewer->setSceneData(geode);
    }


    osg::Camera* getCamera()
    {
        return camera;
    }



    void keyPressEvent(QKeyEvent *event){
        GameWorld* game_world = GameWorld::getHandle();
//        btosgVehicle *myVehicle=game_world->myVehicle;
        btosgMyCar *myVehicle=game_world->myVehicle;
        auto pos=myVehicle->vehicle->getChassisWorldTransform().getOrigin();
        std::cout<< pos.x() << " " << pos.y() << " " << pos.z() << " " << std::endl;
        switch (event->key()) {
        case Qt::Key_Enter:
//            if(myVehicle->vehicle->getForwardVector())
//            myVehicle->addPower();
            myVehicle->setPower(51);
            myVehicle->vehicle->applyEngineForce(1000, 2);
            myVehicle->vehicle->applyEngineForce(1000, 3);

//            myVehicle->vehicle->applyEngineForce(1500, 6);
//            myVehicle->vehicle->applyEngineForce(1500, 7);
            break;
        case Qt::Key_Up:
            myVehicle->setPower(52);
            myVehicle->vehicle->applyEngineForce(1000, 2);
            myVehicle->vehicle->applyEngineForce(1000, 3);
//            myVehicle->vehicle->applyEngineForce(1500, 6);
//            myVehicle->vehicle->applyEngineForce(1500, 7);
            break;
        case Qt::Key_Down:
            myVehicle->setPower(25);
            myVehicle->vehicle->applyEngineForce(-1000, 2);
            myVehicle->vehicle->applyEngineForce(-1000, 3);
//            myVehicle->vehicle->applyEngineForce(-1500, 6);
//            myVehicle->vehicle->applyEngineForce(-1500, 7);
            break;
        case Qt::Key_Left:

            myVehicle->vehicle->setSteeringValue(btScalar(0.4), 0);
            myVehicle->vehicle->setSteeringValue(btScalar(0.4), 1);
//            myVehicle->vehicle->setSteeringValue(btScalar(0.4), 2);
//            myVehicle->vehicle->setSteeringValue(btScalar(0.4), 3);
            break;
        case Qt::Key_Right:
            myVehicle->vehicle->setSteeringValue(btScalar(-0.4), 0);
            myVehicle->vehicle->setSteeringValue(btScalar(-0.4), 1);
//            myVehicle->vehicle->setSteeringValue(btScalar(-0.4), 2);
//            myVehicle->vehicle->setSteeringValue(btScalar(-0.4), 3);
            break;
        case Qt::Key_C:
//            myVehicle->addPower();
//            myVehicle->addPower();
//            myVehicle->addPower();
            myVehicle->setPower(66);
            myVehicle->vehicle->applyEngineForce(10000, 2);
            myVehicle->vehicle->applyEngineForce(10000, 3);
//            myVehicle->vehicle->applyEngineForce(5000, 6);
//            myVehicle->vehicle->applyEngineForce(5000, 7);
            break;
        case Qt::Key_V:
//            myVehicle->addPower();
//            myVehicle->addPower();
//            myVehicle->addPower();
//            myVehicle->addPower();
//            myVehicle->addPower();
//            myVehicle->addPower();
            myVehicle->setPower(99);
            myVehicle->vehicle->applyEngineForce(30000, 2);
            myVehicle->vehicle->applyEngineForce(30000, 3);
//            myVehicle->vehicle->applyEngineForce(5000, 6);
//            myVehicle->vehicle->applyEngineForce(5000, 7);
            break;

        case Qt::Key_Space:
        {
//            myVehicle->addPower();
//            myVehicle->addPower();
//            myVehicle->addPower();
//            myVehicle->addPower();
            myVehicle->setPower(87);
            btVector3 jumpImpulse(0.0f, 100.f, 30000.f); // 定义向上的冲量大小
            myVehicle->body->applyCentralForce(jumpImpulse);
            break;
        }
        case Qt::Key_Z:

            myVehicle->vehicle->setBrake(3000,2);
            myVehicle->vehicle->setBrake(3000,3);
            break;







        }
         //这里添加OSG处理机制

            if (queue) {
                int key = 0;
                switch (event->key()) {
                    case Qt::Key_Left: key = osgGA::GUIEventAdapter::KEY_Left; break;
                    case Qt::Key_Right: key = osgGA::GUIEventAdapter::KEY_Right; break;
                    case Qt::Key_Up: key = osgGA::GUIEventAdapter::KEY_Up; break;
                    case Qt::Key_Down: key = osgGA::GUIEventAdapter::KEY_Down; break;
                    case Qt::Key_S: key=osgGA::GUIEventAdapter::KEY_S;break;
                    default: return; // 如果不是我们处理的按键，直接返回
                }
                queue->keyPress(key);
            }


    }

    //这里是轮胎的转动，要转回去


    void keyReleaseEvent(QKeyEvent *event){
        GameWorld* game_world = GameWorld::getHandle();
//        btosgVehicle *myVehicle=game_world->myVehicle;
        btosgMyCar *myVehicle=game_world->myVehicle;
        auto pos=myVehicle->vehicle->getChassisWorldTransform().getOrigin();
        std::cout<< pos.x() << " " << pos.y() << " " << pos.z() << " " << std::endl;
        switch (event->key()) {
        case Qt::Key_C:
            myVehicle->vehicle->applyEngineForce(0, 2);
            myVehicle->vehicle->applyEngineForce(0, 3);
//            myVehicle->vehicle->applyEngineForce(0, 6);
//            myVehicle->vehicle->applyEngineForce(0, 7);
            break;
        case Qt::Key_Enter:
            myVehicle->vehicle->applyEngineForce(0, 2);
            myVehicle->vehicle->applyEngineForce(0, 3);
//            myVehicle->vehicle->applyEngineForce(0, 6);
//            myVehicle->vehicle->applyEngineForce(0, 7);
            break;
        case Qt::Key_Up:
            myVehicle->vehicle->applyEngineForce(0, 2);
            myVehicle->vehicle->applyEngineForce(0, 3);
//            myVehicle->vehicle->applyEngineForce(0, 6);
//            myVehicle->vehicle->applyEngineForce(0, 7);
            break;
        case Qt::Key_Down:
            myVehicle->vehicle->applyEngineForce(0, 2);
            myVehicle->vehicle->applyEngineForce(0, 3);
//            myVehicle->vehicle->applyEngineForce(0, 6);
//            myVehicle->vehicle->applyEngineForce(0, 7);
            break;
        case Qt::Key_Left:
            myVehicle->vehicle->setSteeringValue(btScalar(0), 0);
            myVehicle->vehicle->setSteeringValue(btScalar(0), 1);
//            myVehicle->vehicle->setSteeringValue(btScalar(0), 2);
//            myVehicle->vehicle->setSteeringValue(btScalar(0), 3);
            break;
        case Qt::Key_Right:
            myVehicle->vehicle->setSteeringValue(btScalar(0), 0);
            myVehicle->vehicle->setSteeringValue(btScalar(0), 1);
//            myVehicle->vehicle->setSteeringValue(btScalar(0), 2);
//            myVehicle->vehicle->setSteeringValue(btScalar(0), 3);
            break;
        case Qt::Key_V:
            myVehicle->vehicle->applyEngineForce(0, 2);
            myVehicle->vehicle->applyEngineForce(0, 3);
    //            myVehicle->vehicle->applyEngineForce(5000, 6);
    //            myVehicle->vehicle->applyEngineForce(5000, 7);
            break;
//        case Qt::Key_Space:
//            btVector3 jumpImpulse(0.0f, 0.f, 0.f); // 定义向上的冲量大小
//            myVehicle->body->applyCentralForce(jumpImpulse);
//            break;



        }


            if (queue) {
                int key = 0;
                switch (event->key()) {

                    case Qt::Key_S: key=osgGA::GUIEventAdapter::KEY_S;break;
                    default: return; // 如果不是我们处理的按键，直接返回
                }
                queue->keyRelease(key);
            }


    }
};



#endif // QTOSGWIDGET_H
